package com.cskaoyan.javase.object._6clone.depth;

/**
 * 深度克隆(了解)
 *
 * 浅克隆: Object类当中默认实现的clone方法,就是浅克隆
 *      它指的是,对象中的基本数据类型成员变量,完全克隆一份独立的
 *      但是对象中的引用数据类型成员变量,存储的是引用,这时只会克隆一份引用
 *      这就意味着原先的引用和克隆对象中的引用要指向同一个对象
 *      这时的克隆对象和原先对象不能算完全独立的
 *
 * 深度克隆
 *      深度克隆要求不管对象有没有引用数据类型成员变量,都要能够得到一个完全独立的对象
 *      那怎么办呢?
 *      最简单实现方式:
 *          1.深度克隆是在浅克隆的基础上进行的
 *          2.将对象中引用数据类型成员变量引用指向的对象,克隆一份
 *          3.将克隆对象中的克隆引用指向新的克隆对象
 *
 * @since 17:30
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Teacher t = new Teacher(18, 10000, new A(666));
        Teacher cloneTeacher = t.clone();
        t.age = 25;
        System.out.println(cloneTeacher.age);
        t.a.num = 777;
        System.out.println(cloneTeacher.a.num);
    }
}

class Teacher implements Cloneable {
    int age;
    double salary;
    A a;

    public Teacher(int age, double salary, A a) {
        this.age = age;
        this.salary = salary;
        this.a = a;
    }

    @Override
    protected Teacher clone() throws CloneNotSupportedException {
        // 1.深度克隆是在浅克隆的基础上进行的
        Teacher cloneTeacher = (Teacher) super.clone();
        // 2.将对象中引用数据类型成员变量引用指向的对象,克隆一份
        A cloneA = a.clone();
        // 3.将克隆对象中的克隆引用指向新的克隆对象
        cloneTeacher.a = cloneA;
        return cloneTeacher;
    }
}

class A implements Cloneable{
    int num;

    public A(int num) {
        this.num = num;
    }

    @Override
    protected A clone() throws CloneNotSupportedException {
        return (A) super.clone();
    }
}